import { defineStore } from 'pinia'
import router, { asyncRoutes } from '@/router'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { login, logout, getInfo } from '@/api/user'
import { useTagsViewStore } from '@/store/tagsView'
import { usePermissionStore } from '@/store/permission'

const resetRouter = () => {
  const asyncRouterArr = asyncRoutes.map(item => item.name)
  asyncRouterArr.forEach(name => {
    if (router.hasRoute(name)) {
      router.removeRoute(name)
    }
  })
}

export const useUserStore = defineStore('user', {
  state: () => {
    return {
      token: getToken(),
      name: '',
      avatar: '',
      introduction: '',
      roles: []
    }
  },
  actions: {
    SET_TOKEN(token: string) {
      this.token = token
      setToken(token)
    },
    login({ username, password }: { username: string, password: any }) {
      return new Promise((resolve, reject) => {
        login({ username: username, password: password }).then(response => {
          const { data: { token } } = response
          this.SET_TOKEN(token)
          resolve(null)
        }).catch(error => {
          reject(error)
        })
      })
    },
    logout() {
      return new Promise((resolve, reject) => {
        logout()
          .then(() => {
            this.resetState().then(() => {
              resolve(null)
            })
          })
          .catch(error => {
            reject(error)
          })
      })
    },
    getInfo() {
      return new Promise((resolve, reject) => {
        getInfo({ token: this.token }).then(res => {
          const { data } = res
          if (!data) {
            reject('验证失败，请重新登录！')
          }
          const { roles, name, avatar, introduction } = data
          this.$patch({
            roles,
            name,
            avatar,
            introduction
          })
          resolve(data)
        })
      })
    },
    resetState() {
      return new Promise(resolve => {
        this.$patch(state => {
          state.token = ''
          state.name = ''
          state.avatar = ''
          state.introduction = ''
          state.roles = []
        })
        removeToken()
        resetRouter()
        const tagsViewStore = useTagsViewStore()
        tagsViewStore.delAllViews()
        resolve(null)
      })
    },
    resetToken() {
      return new Promise(resolve => {
        this.$patch(state => {
          state.roles = []
          state.token = ''
          resolve(null)
        })
      })
    },
    async changeRoles(role: string) {
      const token = role + '-token'
      this.SET_TOKEN(token)
      const { roles }: any = await this.getInfo()
      resetRouter()
      const permissionStore = usePermissionStore()
      // generate accessible routes map based on roles
      const accessRoutes:any = await permissionStore.generateRoutes(roles)
      
      // dynamically add accessible routes
      accessRoutes.forEach((route: any) => {
        router.addRoute(route)
      })

      // reset visited views and cached views
      const tagsViewStore = useTagsViewStore()
      tagsViewStore.delAllViews()
    }
  }
})